package com.eportal.service.impl;

import java.io.IOException;
import java.math.BigDecimal;
import java.sql.Timestamp;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.http.HttpSession;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.apache.struts2.ServletActionContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.eportal.aop.LogAnnotation;
import com.eportal.api.MdOpenApi;
import com.eportal.api.MdOpenBaseJson;
import com.eportal.base.BaseDAO;
import com.eportal.domain.FeeDetail;
import com.eportal.domain.FeeMain;
import com.eportal.domain.Sysopt;
import com.eportal.exception.MdKnownRunTimeException;
import com.eportal.service.PropertyPayService;
import com.eportal.service.UserMsgService;
import com.eportal.util.Config;
import com.eportal.util.ValidateUtil;
import com.framework.jqgrid.JqGridPager;

/**
 * 缴费管理业务逻辑接口实现
 */
@Service("propertyPayService")
public class PropertyPayServiceImpl implements PropertyPayService {

	private Map<String, Object> result = new HashMap<String, Object>();
	private static Logger log = Logger.getLogger(SysRolesServiceImpl.class.getName());
	 
	@Resource(name="dao")
	private BaseDAO dao;
	@Autowired
	UserMsgService userMsgService;
	
    @Override
    public List<FeeDetail> list(JqGridPager jqGridPager) {
    	String sql = "select t.sid,t.item_name,TO_CHAR (t.ctime,'YYYY-MM-DD hh24:mi:ss') as ctime,TO_CHAR (t.utime,'YYYY-MM-DD hh24:mi:ss') as utime,s.uname as cUserName,sy.uname as uUserName,con.countUser,con.countmoney,con.payuser,con.paymoney  from fee_main t "
				+ "left join t03_community c on t.communityid=c.sid  "
				+ "left join t02_agtent a on t.agtcode=a.agtcode "
				+ "left join sysopt s on t.cUserName =s.sid "
				+ "left join sysopt sy on t.uUserName =sy.sid "
				+ "left join (select t.main_id,count(t.sid) as countUser, nvl(sum(t.amount),0) as countmoney, nvl(sum(case when t.status=3 then 1 else 0 end),0) as payuser, nvl(sum(case when t.status=3 then t.amount else 0 end),0) as paymoney from fee_detail t group by t.main_id) con on con.main_id = t.sid ";
        return dao.query(sql, jqGridPager);
    }
    
    @Override
	public List<FeeDetail> listPropertyPay(JqGridPager jqGridPager) {
    	String sql = "select fd.sid,to_char(fd.again_time,'yyyy-mm-dd HH24:mi:ss') as againtime ,r.room_no,u.cbname as unitName,b.cbname,r.status as roomstatus,r.owner_name,r.owner_tel,fd.amount,fd.status as paystatus,to_char(fd.pay_time,'yyyy-mm-dd HH24:mi:ss') as paytime from fee_detail fd left join T035_ROOM r on fd.room_id=r.sid left join t032_cinstallunit u on r.unit_id=u.sid left join t031_cbuilding b on u.cbuildingid=b.sid";
        return dao.query(sql, jqGridPager);
	}

    @Override
    public FeeDetail add(FeeDetail feeDetail) throws Exception {
    	dao.save(feeDetail);
        return feeDetail;
    }

    @Override
    public void delete(Long id) {
    	FeeDetail feeDetail = (FeeDetail) dao.getById(FeeDetail.class, id);
    	dao.delete(feeDetail);
    }

    @Override
    public void delete(List<Long> ids) {
        for (Long id : ids) {
            delete(id);
        }
    }

    public FeeDetail get(Long sid) {
        return (FeeDetail) dao.getById(FeeDetail.class, sid);
    }

    @Override
	public FeeMain getFeeMain(Long sid) {
    	return (FeeMain) dao.getById(FeeMain.class, sid);
	}
    
    @Override
    public void update(FeeDetail feeDetail) throws Exception {
        
        dao.update(feeDetail);
    }
    
    /**
     * 缴费菜单新增
     */
    @Override
    @LogAnnotation(operateDescribe="缴费菜单新增") 
	public Map<String, Object> addMenuMethod(String itemName,String type) {
    	result = new HashMap<String, Object>();
    	try {
	    	Sysopt  user= (Sysopt)getSession().getAttribute("user");
	    	//社区下是否有房间
	    	StringBuffer countsql = new StringBuffer("select count(sid) from t035_room r where r.communityid=");
	    	countsql.append(user.getCommunityId());
	        int count = dao.count(countsql.toString());
	        if (count < 1) {
	        	result.put("code", 0);
				result.put("msg", "本社区下没有创建房间用户，请先创建");
				return result;
			}
	    	
	    	FeeMain feeMain = new FeeMain();
	    	feeMain.setAgtCode(user.getAgtCode());
	    	feeMain.setCommunityId(user.getCommunityId());
	    	feeMain.setcTime(new Timestamp(System.currentTimeMillis()));
	    	feeMain.setcUserName(Long.toString(user.getSid()));
	    	feeMain.setItemName(itemName);
	    	feeMain.setStatus("1");
	    	feeMain.setType(type);
	    	dao.save(feeMain);
	    	
	    	//新增缴费户数详情
	    	StringBuffer sql = new StringBuffer("insert into fee_detail(sid,agtcode,communityid,main_id,room_id,cusername,ctime) select seq_fee_detail.nextval as sid,c.agtcode,t.communityid,'");
	    			sql.append(feeMain.getSid());
	    			sql.append( "'as main_id,t.sid as room_id,'");
	    			sql.append(user.getSid());
	    			sql.append( "' as cusername,systimestamp as ctime  from t035_room t left join t03_community c on t.communityid=c.sid where t.communityid=");
	    			sql.append(user.getCommunityId());
	    	dao.excute(sql.toString());
	    	result.put("code", 1);
            result.put("msg", "操作成功");
            result.put("objectId", feeMain.getSid());
    	} catch (Exception e) {
    		log.error(this, e);
    		throw new MdKnownRunTimeException("缴费菜单新增异常");
		}
        return result;
	}

	/**
     * 缴费新增保存方法
     * @throws IOException 
     */
	@Override
    @LogAnnotation(operateDescribe="缴费新增")  
    public Map<String, Object> addMethod(FeeDetail feeDetail){
		try {
			String msg = ValidateUtil.validate(feeDetail);
	        if (msg == null || msg.trim().length() == 0) {
	            	Sysopt  user= (Sysopt)getSession().getAttribute("user");
	            	
	            	feeDetail =  add(feeDetail);
	                result.put("code", 1);
	                result.put("msg", "操作成功");
	                result.put("objectId", feeDetail.getSid());
	        } else {
	            result.put("code", 0);
	            result.put("msg", msg);
	        }
		} catch (Exception e) {
			log.error("缴费保存失败", e);
			result.put("code", 0);
			result.put("msg", "操作失败");
		}
        return result;
    }

	 /**
     * 缴费修改保存方法
     */
	@Override
    @LogAnnotation(operateDescribe="缴费信息修改")  
    public Map<String, Object> updateDetailMethod(FeeDetail feeDetail, String msgStatus) {
		try {
	        result.put("objectId", feeDetail.getSid());
        	FeeDetail entity = get(feeDetail.getSid());
//        	boolean ifMsg = false;//是否通知
        	if ("1".equals(entity.getStatus()) || "2".equals(entity.getStatus())) {
        		BigDecimal  amount = feeDetail.getAmount();
				if(amount.compareTo(BigDecimal.ZERO) ==0){
					result.put("code", 0);
					result.put("msg", "金额不能不能为空或为零");
					return result;
				}
				//因为有前面部分，自定义的内容可以为空 by wangk
				/*if ("1".equals(msgStatus) && StringUtils.isBlank(feeDetail.getNoticeContent())) {//通知
						result.put("code", 0);
						result.put("msg", "选择通知时，通知内容不能为空");
						return result;
				}*/
//				if (!(feeDetail.getAmount().compareTo(entity.getAmount())==0) || !feeDetail.getNoticeContent().equals(entity.getNoticeContent())) {
//					ifMsg = true;
//				}
				entity.setAmount(amount);
				entity.setAgainTime(feeDetail.getAgainTime());
				entity.setNoticeContent(feeDetail.getNoticeContent());
				if ("1".equals(entity.getStatus())) {
					entity.setStatus("2");
				}else if (StringUtils.isNotBlank(feeDetail.getPayType())) {//勾选已缴费
					entity.setPayType(feeDetail.getPayType());
					entity.setPayWay("3");
					entity.setStatus("3");
					entity.setPayTime(new Timestamp(System.currentTimeMillis()));
				}
			}
        	Sysopt  user= (Sysopt)getSession().getAttribute("user");
        	entity.setuUserName(Long.toString(user.getSid()));
        	entity.setuTime(new Timestamp(System.currentTimeMillis()));
        	
        	update(entity);
        	//立即通知
        	if ("1".equals(msgStatus)){
        		//通知
        		StringBuffer msg = new StringBuffer();
        		Map<String, Object> feeDetailMap = getFeeDetail(entity.getSid());
        		msg.append("尊敬的业主您好：您");
        		msg.append(feeDetailMap.get("communityname"));
        		msg.append(feeDetailMap.get("cbname"));
        		msg.append(feeDetailMap.get("unitName"));
        		msg.append(feeDetailMap.get("room_no"));
        		msg.append("的");
        		msg.append(feeDetailMap.get("item_name"));
        		msg.append(" 金额为:");
        		msg.append(entity.getAmount());
        		msg.append("元，请及时缴纳，谢谢!");
        		msg.append(feeDetail.getNoticeContent());
        		Map<String, Object> mapDateil = getFeeDetail(feeDetail.getSid());
        		
        		
        		if ("1".equals(mapDateil.get("roomstatus")) && StringUtils.isNotBlank(mapDateil.get("owner_id").toString()) ) {
        			String receiverId =  mapDateil.get("owner_id").toString();//消息接收人为户主
        			try {
            			MdOpenBaseJson json = MdOpenApi.sendMsg(receiverId,null,"user","msg_2");
	        		} catch (Exception e) {
	        			 log.error("推送消息失败",e);
	        		}
        			userMsgService.addUserMsg(msg.toString(), "3", receiverId, entity.getCommunityId(), "1");
        			//Map<String, Object> map = userMsgService.addMethod("1", mapDateil.get("ownerUserId").toString(), msg.toString());
        		}else if("2".equals(mapDateil.get("roomstatus")) && StringUtils.isNotBlank(mapDateil.get("renter_id").toString())) {
        			
        			String receiverId =  mapDateil.get("renter_id").toString();//消息接收人为租户
        			try {
            			MdOpenBaseJson json = MdOpenApi.sendMsg(receiverId,null,"user","msg_2");
	        		} catch (Exception e) {
	        			log.error(this, e);
	        		}
        			userMsgService.addUserMsg(msg.toString(), "3", receiverId, entity.getCommunityId(), "1");
        			//Map<String, Object> map = userMsgService.addMethod("1", mapDateil.get("renteruserId").toString(), msg.toString());
        		}
			}
            result.put("code", 1);
            result.put("msg", "操作成功");
		} catch (Exception e) {
			log.error("缴费更新失败", e);
			result.put("code", 0);
			result.put("msg", "操作失败");
		}
        return result;
    }
	
	
	@Override
	/**
     * 缴费删除方法,主要用于切面记录操作日志
     */
    @LogAnnotation(operateDescribe="缴费删除")  
    public Map<String, Object> deleteMethod(String param_ids) {
        try {
            List<Long> ids = new LinkedList<Long>();
            result.put("objectId", param_ids);
            for (String s : param_ids.split(",")) {
                ids.add(Long.parseLong(s));
            }
            delete(ids);
            result.put("code", 1);
            result.put("msg", "操作成功");
        } catch (Exception e) {
            log.error("缴费删除失败", e);
            result.put("code", 0);
            result.put("msg", "操作失败");
        }
        return result;
    }
	public HttpSession getSession() {
        return ServletActionContext.getRequest().getSession();
    }

	@Override
	@LogAnnotation(operateDescribe="缴费菜单名称修改")  
	public Map<String, Object> updateMenuMethod(String itemName, String sid) {
		try {
			Sysopt  user= (Sysopt)getSession().getAttribute("user");
			FeeMain entity = getFeeMain(Long.parseLong(sid));
			entity.setItemName(itemName);
			entity.setuTime(new Timestamp(System.currentTimeMillis()));
			entity.setuUserName(Long.toString(user.getSid()));
			dao.update(entity);
            result.put("code", 1);
            result.put("msg", "操作成功");
		} catch (Exception e) {
			log.error("缴费更新失败", e);
			result.put("code", 0);
			result.put("msg", "操作失败");
		}
        return result;
	}

/*	@Override
	public Map<String, Object> getFeeDetail(Long sid) {
		List<Map<String, Object>> list= null;
		StringBuilder sql = new StringBuilder("select fd.*,co.communityname,r.room_no,u.cbname as unitName,b.cbname,fm.item_name,r.status as roomstatus,r.owner_name,r.owner_tel,r.owner_id,r.renter_tel,r.renter_name,r.renter_id,us2.userid as ownerUserId,us3.userid as renteruserId,to_char(fd.again_time,'yyyy-mm-dd') as againTime,us.tel as paytel,us.auname as payname "
				+ "from fee_detail fd "
				+ "left join T035_ROOM r on fd.room_id=r.sid "
				+ "left join t032_cinstallunit u on r.unit_id=u.sid "
				+ "left join t031_cbuilding b on u.cbuildingid=b.sid "
				+ "left join t04_users us on fd.pay_userid=us.sid  "
				+ "left join t04_users us2 on r.owner_id=us2.sid "
				+ "left join t04_users us3 on r.renter_id=us3.sid "
				+ "left join  fee_main fm on fd.main_id=fm.sid "
				+ "left join  t03_community co on fd.communityid=co.sid "
				+ "where fd.sid=");
		sql.append(sid);
		list= dao.queryBySql(sql.toString());
		if (list.size()>0) {
			return list.get(0);
		}
		return null;
	}*/
	
	/**
	 * 
	 * 修改：减少了一些不必要的表的关联 by wnagk 2017.03.06
	 */
	public Map<String, Object> getFeeDetail(Long sid) {
		List<Map<String, Object>> list= null;
		StringBuilder sql = new StringBuilder("select fd.*,co.communityname,r.room_no,u.cbname as unitName,b.cbname,fm.item_name,r.status as roomstatus,r.owner_name,r.owner_tel,r.owner_id,r.renter_tel,r.renter_name,r.renter_id,to_char(fd.again_time,'yyyy-mm-dd') as againTime,us.tel as paytel,us.auname as payname "
				+ "from fee_detail fd "
				+ "left join T035_ROOM r on fd.room_id=r.sid "
				+ "left join t032_cinstallunit u on r.unit_id=u.sid "
				+ "left join t031_cbuilding b on u.cbuildingid=b.sid "
				+ "left join t04_users us on fd.pay_userid=us.sid  "
				+ "left join  fee_main fm on fd.main_id=fm.sid "
				+ "left join  t03_community co on fd.communityid=co.sid "
				+ "where fd.sid=");
		sql.append(sid);
		list= dao.queryBySql(sql.toString());
		if (list.size()>0) {
			return list.get(0);
		}
		return null;
	}

	@Override
	public Map<String, Object> countUserPay(String type, String mainid) {
		List<Map<String, Object>> list= null;
		StringBuilder sql = new StringBuilder("select count(t.sid) as countUser, nvl(sum(t.amount),0) as countmoney, nvl(sum(case when t.status=3 then 1 else 0 end),0) as payuser, nvl(sum(case when t.status=3 and t.pay_type='1' then t.amount else 0 end),0) as paymoney"
				+ " from fee_detail t where ");
		Sysopt  user= (Sysopt)getSession().getAttribute("user");
		int userRole =  (Integer) getSession().getAttribute("userRole");
		if(StringUtils.isBlank(mainid)){
			switch (userRole) {
			case 1:
			case 2:	
				sql.append(" t.main_id in( select m.sid from FEE_MAIN m where m.type=");
				sql.append(type);
				sql.append(")");
				break;
			case 21:	
				sql.append(" t.main_id in( select m.sid from FEE_MAIN m left join T02_AGTENT a on m.agtcode=a.agtcode where m.type=");
				sql.append(type);
				sql.append(" and a.sysoptId=");
				sql.append(user.getSid());
				sql.append(")");
				break;
			case 3:
			case 4:	
				sql.append(" t.main_id in( select m.sid from FEE_MAIN m where m.type=");
				sql.append(type);
				sql.append(" and m.agtcode='");
				sql.append(user.getAgtCode());
				sql.append("')");
				break;
			case 5:
			case 6:	
				sql.append(" t.main_id in( select m.sid from FEE_MAIN m where m.type=");
				sql.append(type);
				sql.append(" and m.communityid='");
				sql.append(user.getCommunityId());
				sql.append("')");
				break;
			default:
				return null;
			}
		}else{
			sql.append(" t.main_id ='");
			sql.append(mainid);
			sql.append("'");
		}
		list= dao.queryBySql(sql.toString());
		if (list.size()>0) {
			return list.get(0);
		}
		return null;
	}

	@Override
	public List<FeeMain> list(String hql) {
		return dao.query(hql);
	}
	
}
